package com.zhangtai.modules.controller.admin;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhangtai.common.annotation.SysAuthorityLog;
import com.zhangtai.modules.constVo.InsuranceConst;
import com.zhangtai.modules.controller.aouthLogin.LoginController;
import com.zhangtai.modules.dao.ConfigDao;
import com.zhangtai.modules.dao.EmployeeInsuranceDao;
import com.zhangtai.modules.dto.*;
import com.zhangtai.modules.entity.employee.EmployeeInfoEntity;
import com.zhangtai.modules.entity.insurance.EmployeeInsuranceEntity;
import com.zhangtai.modules.entity.insurance.InsuranceChangeEntity;
import com.zhangtai.modules.entity.insurance.InsuranceEntity;
import com.zhangtai.modules.entity.system.ConfigEntity;
import com.zhangtai.modules.service.baseFromMssql.BaseMssqlServiceImpl;
import com.zhangtai.modules.service.employee.EmployeeInfoService;
import com.zhangtai.modules.service.insurance.EmployeeInsuranceService;
import com.zhangtai.modules.service.insurance.InsuranceChangeService;
import com.zhangtai.modules.service.insurance.InsuranceService;
import com.zhangtai.modules.vo.*;
import com.zhangtai.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@Slf4j
@RequestMapping("insurance")
@Api(tags = "雇主险")
public class InsuranceController {

    @Autowired
    private InsuranceService insuranceService;
    @Autowired
    private EmployeeInsuranceService employeeInsuranceService;
    @Autowired
    private EmployeeInsuranceDao employeeInsuranceDao;
    @Autowired
    private EmployeeInfoService employeeInfoService;
    @Autowired
    private LoginController loginController;
    @Autowired
    private InsuranceChangeService insuranceChangeService;
    @Autowired
    private JobController jobController;
    @Autowired
    private ConfigDao configDao;
    @Autowired
    private BaseMssqlServiceImpl baseMssqlService;

    @PostMapping("/saveOrUpdateInsurance")
    @ApiOperation("保存雇主方案id")
    @PreAuthorize("hasAuthority('emp:security:update')")
    public R saveOrUpdateInsurance(@RequestBody @Valid InsuranceEntity entity,HttpServletRequest request)throws Exception{
        R uR = loginController.getUserInfo(request);
        JSONObject user = (JSONObject) uR.getData();
        String userCode = null ;
        String name =null;
        Long unitId = null;
        if(!ObjectUtils.isEmpty(user)){
            userCode = user.getString("usercode");
            name = user.getString("name");
            unitId = user.getLong("depId");
        }
        entity.setOperateTime(new Date());
        entity.setOperateCode(userCode);
        entity.setOperateName(name);
        if(ObjectUtils.isEmpty(entity.getId())){
            entity.setNumber(0);
            entity.setUnitId(unitId);
            insuranceService.saveE(entity);
        }else{
            insuranceService.updateByIdE(entity);
        }

        return R.ok();
    }

    @PostMapping("/getInsuranceList")
    @ApiOperation("获取雇主险列表")
    @PreAuthorize("hasAuthority('emp:security:update')")
    public R<PageResult<InsuranceDto>> getInsuranceList(@RequestBody @Valid InsuranceVo insuranceVo,HttpServletRequest request)throws Exception{

        PageResult<InsuranceDto> result = insuranceService.getInsuranceList(insuranceVo.getCompanyId(),insuranceVo.getInsuranceUnit(),
                insuranceVo.getStatus(),insuranceVo.getStartTime(),insuranceVo.getEndTime(),insuranceVo.getNumber(),insuranceVo.getPageNum(),insuranceVo.getPageSize());

        return R.ok(result);
    }

    @PostMapping("/deleteSecurity")
    @ApiOperation("删除雇主保险方案")
    @SysAuthorityLog(value = "删除雇主保险方案")
    @PreAuthorize("hasAuthority('emp:security:delete')")
    @Transactional
    public R deleteSecurity(String insuranceId,HttpServletRequest request)throws Exception{
        List<EmployeeInsuranceDto> list = employeeInsuranceDao.getMemberList(Long.parseLong(insuranceId));
        for(EmployeeInsuranceDto entity:list){
            InsuranceChangeVo changeVo = new InsuranceChangeVo();
            changeVo.setType(InsuranceConst.INSURANCE_TYPE_REDUCE);
            changeVo.setStatus(InsuranceConst.INSURANCE_STATUS_UNVAILD);
            changeVo.setInsuranceId(entity.getInsuranceId());
            changeVo.setOrgId(entity.getOrgId());
            changeVo.setUnitId(entity.getUnitId());
            changeVo.setOid(entity.getOid());
            changeSecurity(changeVo,request,null,null);
        }
        //删除雇主保险方案
        insuranceService.unValidOne(Long.parseLong(insuranceId));
        //删除个人对应雇主保险
        employeeInsuranceDao.removeAllEmployeeInsurance(Long.parseLong(insuranceId));
        return R.ok();
    }

    /**
     *
     * @param voList
     * @return
     */
    @PostMapping("/saveOrUpdateEmployeeSecurity")
    @ApiOperation("保存个人雇主险方案")
    @SysAuthorityLog(value = "保存个人雇主险方案")
    @Transactional
    @PreAuthorize("hasAuthority('emp:securityEmp:update')")
    public R saveOrUpdateEmployeeSecurity(@RequestBody @Valid List<EmployeeInsuranceVo> voList,HttpServletRequest request)throws Exception{
        ConfigEntity configEntity = getInsuranceConfig().getData();
        if(ObjectUtils.isEmpty(configEntity)){
            return R.error("雇主险配置未生效，无法添加人员");
        }else{
            if(configEntity.getIsOpen().equals(0)){
                return R.error("雇主险已停止增员，无法添加/删除人员");
            }
        }
        //查出公积金所有明细
        JSONObject obj = loginController.getUserInfo(request).getData();
        String userName = obj.getString("name");
        String code = obj.getString("usercode");
        String erroMsg = "";
        boolean isSuccess = true;
        for(EmployeeInsuranceVo vo:voList){
            EmployeeInsuranceEntity employeeSecurityEntity = employeeInsuranceDao.selectOne(new QueryWrapper<EmployeeInsuranceEntity>().eq("oid",vo.getOid()).eq("is_delete",0));
            EmployeeInfoEntity infoEntity = employeeInfoService.getByIdE(vo.getOid());
            EmployeeInsuranceEntity user = BeanUtilsMabach.doToDto(vo, EmployeeInsuranceEntity.class);
            InsuranceEntity insuranceEntity =  insuranceService.getByIdE(vo.getInsuranceId());
            if(ObjectUtils.isEmpty(insuranceEntity)){
                return R.error("雇主险方案不存在");
            }

            if(!ObjectUtils.isEmpty(employeeSecurityEntity)){
                if(employeeSecurityEntity.getStatus().equals("1")){
                    isSuccess = false;
                    erroMsg += employeeSecurityEntity.getName()+"、";
                    continue;
                }
                user.setId(employeeSecurityEntity.getId());
            }
            user.setUnitId(infoEntity.getUnitId());
            user.setOperaterCode(code);
            user.setOperateTime(new Date());
            user.setOperateName(userName);
            if(!ObjectUtils.isEmpty(user.getId())){
                employeeInsuranceDao.updateById(user);

            }else{
                employeeInsuranceDao.insert(user);
            }

            if(ObjectUtils.isEmpty(vo.getId())){
                //插入新增记录
                InsuranceChangeVo changeVo = new InsuranceChangeVo();
                EmployeeInfoEntity employeeInfoEntity = employeeInfoService.getByIdE(vo.getOid());
                if(!ObjectUtils.isEmpty(employeeInfoEntity)){
                    changeVo.setOrgId(employeeInfoEntity.getOrgId());
                    changeVo.setUnitId(employeeInfoEntity.getUnitId());
                }
                //更新入社保方案人数
                if(!ObjectUtils.isEmpty(insuranceEntity)){
                    if(insuranceEntity.getNumber()>=insuranceEntity.getMaxNumber()){
                        return R.error("超过最大投保人数");
                    }
                    insuranceEntity.setNumber(insuranceEntity.getNumber()+1);
                    insuranceService.updateByIdE(insuranceEntity);
                }
                changeVo.setType(InsuranceConst.INSURANCE_TYPE_ADD);
                changeVo.setStatus(insuranceEntity.getStatus());
                changeVo.setInsuranceId(user.getInsuranceId());
                changeVo.setOid(user.getOid());

                changeSecurity(changeVo,request,null,null);

            }else{
                InsuranceChangeVo changeVo = new InsuranceChangeVo();
                changeVo.setInsuranceId(vo.getInsuranceId());
                changeVo.setOid(user.getOid());
                EmployeeInfoEntity employeeInfoEntity = employeeInfoService.getByIdE(vo.getOid());
                if(!ObjectUtils.isEmpty(employeeInfoEntity)){
                    changeVo.setOrgId(employeeInfoEntity.getOrgId());
                    changeVo.setUnitId(employeeInfoEntity.getUnitId());
                }
                if(vo.getStatus().equals(InsuranceConst.INSURANCE_STATUS_UNVAILD)){
                    changeVo.setType(InsuranceConst.INSURANCE_TYPE_REDUCE);
                    changeVo.setStatus(InsuranceConst.INSURANCE_STATUS_UNVAILD);
                //更新入社保方案人数
                if(!ObjectUtils.isEmpty(insuranceEntity)){
                    insuranceEntity.setNumber(insuranceEntity.getNumber()-1);
                    insuranceService.updateByIdE(insuranceEntity);
                }
                }else{
                    changeVo.setType(InsuranceConst.INSURANCE_TYPE_ADD);
                    changeVo.setStatus(InsuranceConst.INSURANCE_STATUS_AVAILD);
                    //更新入社保方案人数
                    if(!ObjectUtils.isEmpty(insuranceEntity)){
                        if(insuranceEntity.getNumber()>=insuranceEntity.getMaxNumber()){
                            return R.error("超过最大投保人数");
                        }
                        insuranceEntity.setNumber(insuranceEntity.getNumber()+1);
                        insuranceService.updateByIdE(insuranceEntity);
                    }
                }
                changeSecurity(changeVo,request,null,null);
            }
        }
        if(isSuccess){
            return R.ok();
        }else{
            erroMsg += "已存在生效的雇主险方案";
            return R.error(erroMsg);
        }

    }


    @PostMapping("/changeSecurity")
    @ApiOperation("保存雇主险增员/减员记录")
    @SysAuthorityLog(value = "保存雇主险增员/减员记录")
    @Transactional
    @PreAuthorize("hasAuthority('emp:socialSecurity:update')")
    public R changeSecurity(@RequestBody @Valid InsuranceChangeVo insuranceChangeVo, HttpServletRequest request, String n, String code)throws Exception{
        InsuranceChangeEntity changeEntity = BeanUtilsMabach.doToDto(insuranceChangeVo, InsuranceChangeEntity.class);
        changeEntity.setOperationTime(new Date());
        R uR = loginController.getUserInfo(request);
        JSONObject user = (JSONObject) uR.getData();
        String userCode = code;
        String name = n;
        if(!ObjectUtils.isEmpty(user)){
            userCode = user.getString("usercode");
            name = user.getString("name");
        }
        changeEntity.setOperaterCode(userCode);
        changeEntity.setOperateName(name);
        insuranceChangeService.saveE(changeEntity);
        return R.ok();
    }

    @PostMapping("/getInsuranceEmployeeInfo")
    @ApiOperation("获取方案员工列表")
    @PreAuthorize("hasAuthority('emp:securityEmp:update')")
    public R<List<EmployeeInsuranceDto>> getInsuranceEmployeeInfo(String insuranceId){

        List<EmployeeInsuranceDto> list =employeeInsuranceService.getEmployeeList(Long.parseLong(insuranceId));
        for(EmployeeInsuranceDto dto:list){
            dto.setJobname(jobController.jobMap.get(dto.getJobId()));
            dto.setOrgname(jobController.orgMap.get(dto.getOrgId()));
            dto.setUnitname(jobController.orgMap.get(dto.getUnitId()));
        }
        return R.ok(list);
    }

    @PostMapping("/getMemberRecord")
    @ApiOperation("获取参保台账")
    @PreAuthorize("hasAuthority('emp:securityEmp:update')")
    public R<PageResult<InsuranceMemberRecordDto>> getMemberRecord(@RequestBody @Valid InsuranceMemberVo vo,HttpServletRequest request)throws Exception{
        //获取当前用户角色下公司Id
        R checkR = loginController.checkOrgPermission(request, null, false);
        if (!R.isOk.equals(checkR.getStatus())) {
            return R.error();
        }
        List<Long> orgIds = (List<Long>) checkR.getData();
        List<Long> orgId = null;
        if(!StringUtils.isEmpty(vo.getOrgname())){
            orgId = baseMssqlService.finOrgByOrgName(vo.getOrgname());
        }
        PageResult<InsuranceMemberRecordDto> list =employeeInsuranceService.getMemberRecord(orgIds,vo.getCompanyName(),vo.getEmployeestatus(),vo.getStatus(),vo.getSecurityStatus(),
                vo.getOperateName(),orgId,vo.getPageNum(),vo.getPageSize());
        List<InsuranceMemberRecordDto> recordDtoList = list.getList();
        for(InsuranceMemberRecordDto dto:recordDtoList){
            dto.setJobLevel(jobController.jobLevelMap.get(dto.getJobLevelId()));
            dto.setUnitname(jobController.orgMap.get(dto.getUnitId()));
            dto.setJobname(jobController.jobMap.get(dto.getJobId()));
            dto.setOrgname(jobController.orgMap.get(dto.getOrgId()));
        }
        list.setList(recordDtoList);
        return R.ok(list);
    }

    @PostMapping("/getMemberChange")
    @ApiOperation("查询雇主险人员变更记录")
    @PreAuthorize("hasAuthority('emp:socialSecurity:get')")
    public R<PageResult<InsuranceChangeDto>> getMemberChange(@RequestBody @Valid InsuranceChangeListVo vo, HttpServletRequest request)throws Exception{
        //获取当前用户角色下公司Id
        R checkR = loginController.checkOrgPermission(request, null, false);
        if (!R.isOk.equals(checkR.getStatus())) {
            return R.error();
        }
        List<Long> orgIds = (List<Long>) checkR.getData();
        List<Long> orgId = null;
        if(!StringUtils.isEmpty(vo.getOrgname())){
            orgId = baseMssqlService.finOrgByOrgName(vo.getOrgname());
        }
        PageResult<InsuranceChangeDto> pageResult  = insuranceChangeService.getChangeList(orgIds,vo.getStartTime(),vo.getEndTime(),
                vo.getCompanyName(),vo.getEmployeestatus(),vo.getType(),vo.getSecurityType(),vo.getOperateName(),orgId,vo.getPageNum(),vo.getPageSize());
        List<InsuranceChangeDto> list = pageResult.getList();
        for(InsuranceChangeDto dto:list){
            dto.setJobLevel(jobController.jobLevelMap.get(dto.getJobLevelId()));
            dto.setUnitName(jobController.orgMap.get(dto.getUnitId()));
            dto.setJobName(jobController.jobMap.get(dto.getJobId()));
            dto.setOrgName(jobController.orgMap.get(dto.getOrgId()));
        }
        return R.ok(pageResult);
    }

    @PostMapping("/getAllInsuranceList")
    @ApiOperation("获取所有有效方案")
    public R<List<InsuranceEntity>> getAllInsuranceList(){
        return R.ok(insuranceService.getAllInsuranceList());
    }


    @PostMapping("/updateInsuranceConfig")
    @ApiOperation("更新雇主险配置")
    @PreAuthorize("hasAuthority('emp:gzzrx:opreateControl')")
    public R updateInsuranceConfig(Integer status){
        ConfigEntity configEntity = configDao.selectOne(new QueryWrapper<ConfigEntity>().eq("name","insurance_config").eq("is_delete",0));
        configEntity.setIsOpen(status);
        configDao.updateById(configEntity);
        return R.ok();
    }

    @PostMapping("/getInsuranceConfig")
    @ApiOperation("获取雇主险配置")
//    @PreAuthorize("hasAuthority('emp:gzzrx:opreateControl')")
    public R<ConfigEntity> getInsuranceConfig(){
        ConfigEntity configEntity = configDao.selectOne(new QueryWrapper<ConfigEntity>().eq("name","insurance_config").eq("is_delete",0));
        return R.ok(configEntity);
    }
}
